package com.jplus.framework.mvc;

import javax.servlet.AsyncContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jplus.framework.AppConstant;
import com.jplus.framework.bean.BeanHandle;
import com.jplus.framework.mvc.action.Handler;
import com.jplus.framework.mvc.handler.HandlerExceptionResolver;
import com.jplus.framework.mvc.handler.HandlerInvoker;
import com.jplus.framework.mvc.handler.HandlerMapping;

/**
 * 异步Servlet处理<br>
 * 异步并不是我用了Thread就异步了，而是使用了Servlet3.0的AsyncContext 特性。
 * 
 * @author Yuanqy
 *
 */
public class ServletThread extends Thread {
	Logger logger = LoggerFactory.getLogger(getClass());
	private AsyncContext asyncContext;
	private HttpServletRequest req;
	private HttpServletResponse res;

	private HandlerMapping handlerMapping = BeanHandle.getBean(HandlerMapping.class);
	private HandlerInvoker handlerInvoker = BeanHandle.getBean(HandlerInvoker.class);
	private HandlerExceptionResolver handlerExceptionResolver = BeanHandle.getBean(HandlerExceptionResolver.class);

	public ServletThread(AsyncContext asyncContext, int timeout) {
		this.asyncContext = (asyncContext);
		this.asyncContext.setTimeout(timeout);
		this.req = ((HttpServletRequest) asyncContext.getRequest());
		this.res = ((HttpServletResponse) asyncContext.getResponse());
	}

	@Override
	public void run() {
		try {
			// 初始化 DataContext
			DataContext.init(req, res);
			// 获取当前请求相关数据
			String currentRequestMethod = req.getMethod();
			String currentRequestPath = WebUtil.getRequestPath();
			logger.debug("[Action] {}:{}", currentRequestMethod, currentRequestPath);
			// 将“/”请求重定向到首页
			if (currentRequestPath.equals("/")) {
				WebUtil.redirectRequest(AppConstant.CONFIG.AppHomePage.getValue());
				return;
			}
			// 去掉当前请求路径末尾的“/”
			if (currentRequestPath.endsWith("/")) {
				currentRequestPath = currentRequestPath.substring(0, currentRequestPath.length() - 1);
			}
			// 获取 Handler
			Handler handler = handlerMapping.getHandler(currentRequestMethod, currentRequestPath);
			// 若未找到 Action，则跳转到 404 页面
			if (handler == null) {
				logger.warn("This request is not found action classes,[{}]{}", currentRequestMethod, currentRequestPath);
				WebUtil.sendError(HttpServletResponse.SC_NOT_FOUND, "");
				return;
			}
			// 调用 Handler
			handlerInvoker.invokeHandler(handler);
		} catch (Exception e) {
			e.printStackTrace();
			// 处理 Action 异常
			handlerExceptionResolver.resolveHandlerException(e);
		} finally {
			DataContext.destroy();// 一定要注意销毁
			asyncContext.complete();// 一定要通知完成
		}
	}
}
